/*
* Copyright (C) 2020 ~ 2023 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkRtp/MkRtpUdpServer.h"
#include "MkEvent/MkEventPool.h"
#include "MkEvent/MkTimer.h"
#include "MkEvent/MkEvent.h"
#include <gtest/gtest.h>

TEST(RtpUtpSocket, RtpUtpTest)
{
    CMkEventPool* pEventPool = new CMkEventPool;
    pEventPool->Start();
    CMkTimer* pTimer = new CMkTimer;
    pTimer->StartTimerThread();

    CMkRtpUdpServer::SetRtcpCheckFlag(TRUE);
    CMkRtpUdpServer::SetRtcpTimeOutSec(10);
    CMkRtpUdpServer* pRtpSender = new CMkRtpUdpServer(pEventPool->GetFreeEvent(), pTimer);
    CMkRtpUdpServer* pRtpRecver = new CMkRtpUdpServer(pEventPool->GetFreeEvent(), pTimer);
    pRtpSender->Start(50006);
    pRtpRecver->Start(50008);
    Uint16 RtpPort = pRtpSender->GetRtpPort();
    EXPECT_EQ(RtpPort, 50006);
    RtpPort = pRtpRecver->GetRtpPort();
    EXPECT_EQ(RtpPort, 50008);
    Uint16 RtcpPort = pRtpSender->GetRtcpPort();
    EXPECT_EQ(RtcpPort, 50007);
    RtcpPort = pRtpRecver->GetRtcpPort();
    EXPECT_EQ(RtcpPort, 50009);
    MkRtpRemoter Remoter;
    Remoter.RtpRemoteHost = "127.0.0.1";
    Remoter.RtpRemotePort = 50006;
    Remoter.Payload = 100;
    Remoter.RtpType = MkRtpSendRecver;
    Remoter.Ssrc = 123;
    Remoter.RtpPacketCb = [](const CMkRtpPacket& RtpPacket, const MkString& Host, Uint16 Port) {
        EXPECT_EQ(Port, 50006);
        EXPECT_STREQ("127.0.0.1", Host.c_str());
        EXPECT_EQ(123, RtpPacket.GetSsrc());
        EXPECT_NE(0, RtpPacket.GetTimeStamp());
        return NoneError;
    };
    pRtpRecver->AddRtpRemoter(123, Remoter);

    MkRtpRemoter SenderRemoter;
    SenderRemoter.RtpRemoteHost = "127.0.0.1";
    SenderRemoter.RtpRemotePort = 50008;
    SenderRemoter.Payload = 100;
    SenderRemoter.RtpType = MkRtpSendRecver;
    SenderRemoter.Ssrc = 123;
    SenderRemoter.RtpPacketCb = [](const CMkRtpPacket& RtpPacket, const MkString& Host, Uint16 Port) {
        EXPECT_EQ(Port, 50008);
        EXPECT_STREQ("127.0.0.1", Host.c_str());
        EXPECT_EQ(123, RtpPacket.GetSsrc());
        EXPECT_NE(0, RtpPacket.GetTimeStamp());
        return NoneError;
    };

    int Index = 1;
    CMkRtpPacket RtpPacket;
    Uint8 pBuf[10] = { 1 };
    RtpPacket.SetPayloadType(100);

    RtpPacket.SetPayloadData(pBuf);
    RtpPacket.SetPayloadLength(10);
    Uint8 pRtpHeader[Len16] = { 0 };
    while (Index < 5) {
        RtpPacket.SetMarker(Index % 2);
        RtpPacket.SetTimeStamp(Index * 40);
        RtpPacket.SetSsrc(123);
        RtpPacket.SetSequenceNumber(Index);
        RtpPacket.PacketHeader(pRtpHeader, Len16);
        pRtpSender->SendRtpPacket(RtpPacket, "127.0.0.1", 50008);

        RtpPacket.SetSsrc(123);
        RtpPacket.SetSequenceNumber(Index);
        RtpPacket.PacketHeader(pRtpHeader, Len16);
        pRtpRecver->SendRtpPacket(RtpPacket, "127.0.0.1", 50006);
        CMkThread::ThreadSleep(1);
        Index++;
    }
    pRtpRecver->OnRtcpCheck();
    pRtpRecver->OnRtcpCheck();
    CMkBufferList BufferList;
    BufferList.Append(pBuf, 10, 1);
    RtpPacket.SetPayloadData(nullptr);
    RtpPacket.SetPayloadLength(0);
    RtpPacket.SetPayloadBufferList(BufferList);
    RtpPacket.AppentPayloadBufferList(pBuf, 1);
    RtpPacket.AppentPayloadBufferList(CMkBuffer(pBuf, 10));
    while (Index < 10) {
        RtpPacket.SetMarker(Index % 2);
        RtpPacket.SetTimeStamp(Index * 40);
        RtpPacket.SetSequenceNumber(Index);
        RtpPacket.SetSsrc(123);
        RtpPacket.PacketHeader(pRtpHeader, Len16);
        pRtpSender->SendRtpPacket(RtpPacket, "127.0.0.1", 50008);

        RtpPacket.SetSsrc(123);
        RtpPacket.SetSequenceNumber(Index);
        RtpPacket.PacketHeader(pRtpHeader, Len16);
        pRtpRecver->SendRtpPacket(RtpPacket, "127.0.0.1", 50006);
        CMkThread::ThreadSleep(1);
        Index++;
    }

    pRtpRecver->SendBuffer(BufferList, 123, 400);
    pRtpSender->SendBuffer(BufferList, 123, 400);

    //send app
    CMkRtcpPacket RtcpApp;
    RtcpApp.SetPayload(MkRtcpApp);
    RtcpApp.SetAppSsrc(123);
    RtcpApp.SetAppName(55);
    RtcpApp.SetAppData("test");

    CMkRtcpPacket RtcpApp2;
    RtcpApp2.SetAppSsrc(123);
    RtcpApp2.SetAppName(55);
    RtcpApp2.SetAppData("test");
    RtcpApp2.SetPayload(MkRtcpApp);
    pRtpSender->SendRtcpPacket(RtcpApp2, "127.0.0.1", 50009);
    pRtpRecver->SendRtcpPacket(RtcpApp, "127.0.0.1", 50007);

    //send bye
    CMkRtcpPacket RtcpBye;
    RtcpBye.ByeAddSsrc(123);
    RtcpBye.SetPayload(MkRtcpBye);
    RtcpBye.SetByeReason("send end");

    CMkRtcpPacket RtcpBye2;
    RtcpBye2.ByeAddSsrc(123);
    RtcpBye2.SetPayload(MkRtcpBye);
    RtcpBye2.SetByeReason("send end");
    pRtpSender->SendRtcpPacket(RtcpBye2, "127.0.0.1", 50009);
    pRtpRecver->SendRtcpPacket(RtcpBye, "127.0.0.1", 50007);

    pTimer->StopTimerThread();
    pEventPool->Stop();
    MkDelete(pRtpSender);
    MkDelete(pRtpRecver);
    MkDelete(pTimer);
    MkDelete(pEventPool);
}